﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using System;
using ConsoleApp.Job.TaskFramework;
using ConsoleAppFramework.Util;
using ConsoleAppFramework.Service;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Threading;
using System.Net.Http;

namespace ConsoleAppFramework.Job.TaskJob
{
    public class 测试任务 : TaskBase
    {
        private static List<Order> orders = new List<Order>();

        public override void Execute()
        {
            //Main();
            //Console.WriteLine("主线程：" + Thread.CurrentThread.ManagedThreadId);
            //TestAsync();
            //Console.WriteLine("GetInfoAsync后 调用线程：" + Thread.CurrentThread.ManagedThreadId);
            //Thread.Sleep(1000);
            //Console.WriteLine("主线程结束 调用线程：" + Thread.CurrentThread.ManagedThreadId);
            //Console.ReadLine();

            //Console.WriteLine("1:" + Thread.CurrentThread.ManagedThreadId);
            //Console.WriteLine("Main方法执行开始");
            //Run();
            //Console.WriteLine("Main方法执行结束");
            //Console.Read();

            //ConsoleExt.WriteLine("--开始!");
            //ConsoleExt.WriteLine($"--下面我（主线程）先通知下儿子（子线程）也开始。 ");
            //// 调用 async 修饰的方法，也就是异步执行的方法
            //AsyncTask(); // 异步方法，不占用主线程，是另新创建的新的子线程
            //ConsoleExt.WriteLine("--我（主线程）已经让我儿子（子线程）开始工作了，我也继续工作");
            //ConsoleExt.WriteLine($"--我（主线程）完成! ");
            //Console.ReadLine();




            #region 内存队列测试

            //for (int i = 0; i < 9000; i++)
            //{
            //    QueueManagerHelper.AddQueueTestModel(new QueueTestModel() { Name = $"Data{i}" });
            //} 

            #endregion

            #region 数据库连接测试
            //DistinctService distinctService = new DistinctService();

            //var distinctList = distinctService.GetList();

            //foreach (var distinct in distinctList)
            //{
            //    ConsoleHelper.WriteInfoLine($"{distinct.Name}");
            //} 
            #endregion

            #region Jobject测试

            ////生成json类型数据
            //JObject obj = new JObject();
            //obj.Add("key1", "value1");
            //obj.Add("key2", "value2");
            //obj.Add("key3", 3);
            //String response = obj.ToString();
            //Console.WriteLine(response);
            //Console.WriteLine("=================================");
            ////解析数值
            //JObject joResponse = (JObject)JsonConvert.DeserializeObject(response);
            //Console.WriteLine(joResponse["key1"].ToString());
            //Console.WriteLine(joResponse["key2"].ToString());
            //Console.WriteLine(joResponse["key3"].ToString());

            ////生成数组
            //JArray jarray = new JArray();
            //JObject jobj = new JObject();
            //jobj.Add("name", "张三");
            //jobj.Add("age", 18);
            //jobj.Add("sex", "男");

            //JObject jobj2 = new JObject();
            //jobj2.Add("name", "李四");
            //jobj2.Add("age", 18);
            //jobj2.Add("sex", "女");

            //jarray.Add(jobj);
            //jarray.Add(jobj2);
            //String response = jarray.ToString();
            //Console.WriteLine(response);
            //Console.WriteLine("============================================");

            ////解析数组
            //JArray ja = (JArray)JsonConvert.DeserializeObject(response);
            ////获取数值
            //foreach (JObject jo in ja)
            //{
            //    string name = jo["name"].ToString();
            //    string age = jo["age"].ToString();
            //    string sex = jo["sex"].ToString();
            //    Console.WriteLine("name=" + name + ", age=" + age + ", sex=" + sex);
            //}

            ////单个数值获取
            //JObject joo = (JObject)ja[1];
            //string name2 = joo["name"].ToString();
            //Console.WriteLine("name2=" + name2);
            //string age2 = joo["age"].ToString();
            //Console.WriteLine("age2=" + age2);
            //string sex2 = joo["sex"].ToString();
            //Console.WriteLine("sex2=" + sex2);

            //var mark = new JObject { { "Name", "Mark" }, { "Age", "8" } };
            //var results = new JArray
            //{
            //    new JObject {{ "Subject", "语文"}, { "Score", 100}},
            //    new JObject {{ "Subject", "数学" }, { "Score", 88}}
            //};
            //mark.Add("Results", results);
            //Console.WriteLine(mark.ToString());

            //var obj = new JObject();
            //var student = new JArray
            //{
            //    new JObject {{ "Name", "Mark" }, { "Age", 8 } },
            //    new JObject {{ "Name", "Jack" }, { "Age", 9 } }
            //};
            //var results = new JArray
            //{
            //    new JObject {{ "Subject", "语文"}, { "Score", 100}},
            //    new JObject {{ "Subject", "数学" }, { "Score", 88}}
            //};
            //obj.Add("Student", student);
            //obj.Add("Results", results);
            //Console.WriteLine(obj.ToString());
            Console.ReadKey();
            #endregion


            static async Task Main()
            {
                Task<int> downloading = DownloadDocsMainPageAsync(); // 【1】
                Console.WriteLine($"启动下载。。。ThreadID:{Thread.CurrentThread.ManagedThreadId}");
                int bytesLoaded = await downloading; // 【3】
                Console.WriteLine($"共下载了 {bytesLoaded} bytes。ThreadID:{Thread.CurrentThread.ManagedThreadId}");
                Console.ReadLine();
            }

                //for (int i = 0; i < 9000000; i++)
                //{
                //    orders.Add(new Order() { Oid = Guid.NewGuid().ToString(), OName = "OrderName_" + i.ToString() });
                //}
                //ConsoleHelper.WriteInfoLine("数据初始化完成");
                ////SendMsgByFeiShu("飞书通知",false);
                //Operation();

                //TaskOperation();

            }
        public void Operation()
        {
            Console.WriteLine("Please write start keys:");
            Console.ReadLine();
            Stopwatch watch = new Stopwatch();
            watch.Start();
            orders.ForEach(order =>
            {
                order.IsSubmit = true;
                int count = 0;
                for (int i = 0; i < 2000; i++)
                {
                    count++;
                }
            });
            watch.Stop();
            Console.WriteLine(watch.ElapsedMilliseconds);
        }
        public void TaskOperation()
        {
            Console.WriteLine("Please write start keys:");
            Console.ReadLine();
            Stopwatch watch = new Stopwatch();
            watch.Start();
            Parallel.ForEach(orders, order =>
            {
                order.IsSubmit = true;
                int count = 0;
                for (int i = 0; i < 2000; i++)
                {
                    count++;
                }
            });
            watch.Stop();
            Console.WriteLine(watch.ElapsedMilliseconds);
        }
        public async static Task TestAsync()
        {
            Console.WriteLine("await1前 调用线程：" + Thread.CurrentThread.ManagedThreadId);
            await Task.Run(() => {
                Console.WriteLine("await1 调用线程：" + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(5000);
                Console.WriteLine("await1 做完了调用线程：" + Thread.CurrentThread.ManagedThreadId);
            });
            Console.WriteLine("await1后 调用线程：" + Thread.CurrentThread.ManagedThreadId);
            await Task.Run(() => {
                Console.WriteLine("await2 调用线程：" + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(5000);
                Console.WriteLine("await2 做完了调用线程：" + Thread.CurrentThread.ManagedThreadId);

            });
            Console.WriteLine("await2后 调用线程：" + Thread.CurrentThread.ManagedThreadId);
        }

        static async void Run()
        {
            Console.WriteLine("2:" + Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("Run方法执行开始");
            await Task.Run(() => {
                Console.WriteLine("Task.Run方法执行开始");
                Console.WriteLine("3:" + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(10000);
                Console.WriteLine("Task.Run方法执行结束");
            });

            Console.WriteLine("4:" + Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("Run方法执行结束");
        }

        // static void Main(string[] args) // 由于在 .Net 7.1 直线 Main 方法不支持 async，所以只能通过 AsyncTask() 来调用异步方法
        //public static async Task Main() // 更新至 .Net 7.1 或更高版本即可用异步 Main() 方法，若其中没有用到 await 关键字，会出现警告：CS1998:此异步方法缺少"await"运算符，将以同步方式运行。。。
        //{
            
        //}
        // async 修饰的方法，也就是异步方法，不占用主线程
        public static async Task AsyncTask()
        {
            Thread.Sleep(1000);
            ConsoleExt.WriteLine($"--我刚到，还没找到儿子（子线程）的房间，");
            var result = await WasteTime(); // 主线程遇到 await，是不会等待的，直接继续执行，接下来的事情交给子线程
            ConsoleExt.WriteLine(result);
            ConsoleExt.WriteLine($"儿子（子线程）已经干完了应该干的事情! ");
        }
        // async 修饰的方法，也就是异步方法，不占用主线程
        private static async Task<string> WasteTime()
        {
            ConsoleExt.WriteLine($"--我终于找到了，下面准备让儿子（子线程）开干！");
            return await Task.Run(() => // 创建一个子线程
            {
                ConsoleExt.WriteLine($"儿子（子线程）开始异步执行了! ");
                // 模拟耗时操作
                Thread.Sleep(5000);
                return $"儿子（子线程）异步执行完了。";
            });
        }
        public static class ConsoleExt
        {
            public static void WriteLine(object message)
            {
                Console.WriteLine($"(Time: {DateTime.Now.ToString("HH:mm:ss.ffffff")},  Thread {Thread.CurrentThread.ManagedThreadId}): {message} ");
            }
            public static async void WriteLineAsync(object message)
            {
                await Task.Run(() => Console.WriteLine($"(Time: {DateTime.Now.ToString("HH:mm:ss.ffffff")},  Thread {Thread.CurrentThread.ManagedThreadId}): {message} "));
            }
        }

        private static async Task<int> DownloadDocsMainPageAsync()
        {
            Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: 即将开始下载。ThreadID:{Thread.CurrentThread.ManagedThreadId}");
            var client = new HttpClient();
            byte[] content = await client.GetByteArrayAsync("https://learn.microsoft.com/en-us/"); // 【2】
            Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: 完成下载。ThreadID:{Thread.CurrentThread.ManagedThreadId}");
            return content.Length;
        }
    }

    public class Order
    {
        public string Oid { get; set; }
        public string OName { get; set; }
        public bool IsSubmit { get; set; }
    }
}
